﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using WcfGeebaServer.Users;
using WcfGeebaServer.DBDAL;
using WcfGeebaServer.Logging;

namespace WcfGeebaServer.ContentManage
{
    [Serializable]
    public class GThread
    {

        #region Fields

        protected int _id;
        protected string _subject;
        protected string _content;
        protected Member _publisher;
        protected DateTime _publishDate;
        protected DateTime _modifiedDate;

        #endregion

        #region DataMembers

        public int Id
        {
            get { return this._id; }
            private set { this._id = value; }
        }

        public string Content
        {
            get
            {
                return this._content;
            }
            set
            {
                this._content = value;
            }
        }

        public DateTime ModifiedDate
        {
            get
            {
                return this._modifiedDate;
            }
            private set
            {
                this._modifiedDate = value;
            }
        }

        public DateTime PublishDate
        {
            get { return this._publishDate; }
        }

        public Member publishedBy
        {
            get { return this._publisher; }
        }

        public string Subject
        {
            get
            {
                return this._subject;
            }
            private set
            {
                this._subject = value;
            }
        }

        #endregion

        #region Ctors

        public GThread(int id, string subject, string content, Member publisher)
        {
            this._id = id;
            this._subject = subject;
            this._content = content;
            this._publisher = publisher;
            this._publishDate = this._modifiedDate = DateTime.Now;
        }

        public GThread(string subject, string content, Member publisher)
            : this(-1, subject, content, publisher)
        {
        }

        public GThread(int id, GThread copy) : this(id, copy.Subject, copy.Content, copy.publishedBy)
        {
            this._publishDate = copy._publishDate;
            this._modifiedDate = copy._modifiedDate;
        }

        public GThread(int id, string subject, string content, Member publisher,
            DateTime publishDate, DateTime modifiedDate) : this(id,subject,content,publisher)
        {
            this._publishDate = publishDate;
            this._modifiedDate = modifiedDate;
        }
        #endregion

        #region Methods

        public virtual bool bump()
        {
            ModifiedDate = DateTime.Now;
            GLogger.log("Thread + " + this.Id + " was bumped");
            return ThreadDA.GetThreadDA().EditThreadContent(this);
        }

        public int addPost(GPost post)
        {
            Member member = GForum.GetForum().GetMember(post.publishedBy.Username);
            if (!GForum.GetForum().Policy.CanPublishMessage(member, GetSubForum(), post))
            {
                return -1;
            }

            post.Id = ThreadDA.GetThreadDA().AddPost(post, this);
            //MemberDA.getMemberDA().incThreadCount(post.publishedBy);
            GLogger.log("Post " + post.Id + " was published by " + post.publishedBy.Username + " with subject " + post.Subject);
            return post.Id;
        }

        public bool removePost(GPost post)
        {
            if (post == null)
            {
                return false;
            }
            bool res = true;
            List<GPost> comments = post.getPosts();
            for (int i = 0; i < comments.Count; i++)
            {
                res &= post.removePost(comments[i]);
            }
            if (res)
            {
                res = ThreadDA.GetThreadDA().RemovePost(post, this);
                if (res)
                {
                    //MemberDA.getMemberDA().decThreadCount(post.publishedBy);
                    GLogger.log("Removed post id=" + post.Id + " containing message:\n" + post.Content);
                }
                else
                {
                    GLogger.error("Problem removing post id=" + post.Id + " containing message:\n" + post.Content, null);
                }
                return res;
            }
            return false;
        }

        public bool removePost(int postID)
        {
            return this.removePost(GetPost(postID));
        }

        public bool editContent(Member member, string newContent)
        {
            if (GForum.GetForum().Policy.CanEditThread(this, member))
            {
                GLogger.log("contents of thread " + this.Id + " was changed");
                this.Content = newContent;
                return ThreadDA.GetThreadDA().EditThreadContent(this);
            }
            return false;
        }

        public List<GPost> getPosts()
        {
            return ThreadDA.GetThreadDA().GetPosts(this);
        }

        public GPost GetPost(int postId)
        {
            return ThreadDA.GetThreadDA().GetPost(postId, this);
        }

        public GSubForum GetSubForum()
        {
            return ThreadDA.GetThreadDA().GetSubforum(this);
        }

        public override int GetHashCode()
        {
            return this.Id;
        }

        public override bool Equals(Object obj)
        {
            if (obj == null)
            {
                return false;
            }

            GThread gth = obj as GThread;
            if ((Object)gth == null)
            {
                return false;
            }

            return this._id == gth._id;
        }

        #endregion
    }
}